import requests
import os
from typing import Optional


def download_file(url: str, local_path: str, chunk_size: int = 8192, timeout: int = 30) -> Optional[str]:
    """
    从指定URL下载文件到本地路径
    
    :param url: 要下载的文件URL
    :param local_path: 本地保存路径（包含文件名）
    :param chunk_size: 下载块大小，默认8192字节
    :param timeout: 超时时间（秒），默认30秒
    :return: 成功返回本地文件路径，失败返回None
    """
    try:
        # 创建目录（如果不存在）
        os.makedirs(os.path.dirname(local_path), exist_ok=True)
        
        # 发送GET请求，流式下载
        with requests.get(url, stream=True, timeout=timeout) as response:
            response.raise_for_status()  # 检查HTTP错误
            
            # 写入文件
            with open(local_path, 'wb') as file:
                for chunk in response.iter_content(chunk_size=chunk_size):
                    if chunk:  # 过滤掉保持连接的空块
                        file.write(chunk)
        
        return local_path
        
    except requests.exceptions.RequestException as e:
        print(f"下载请求错误: {str(e)}")
    except IOError as e:
        print(f"文件写入错误: {str(e)}")
    except Exception as e:
        print(f"下载失败: {str(e)}")
    
    return None


# 使用示例
if __name__ == "__main__":
    # 示例: 下载文件到项目的downloads目录
    file_url = "https://example.com/sample-file.pdf"
    save_path = os.path.join(os.path.dirname(__file__), "downloads", "sample.pdf")
    
    result = download_file(file_url, save_path)
    if result:
        print(f"文件成功下载到: {result}")
    else:
        print("文件下载失败")